/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "随机数.h"

#include <ppl.h>
#include <SIMD/向量运算.h>




int32 f_random_I32(ivec2 区间, int32 随机种子) {
	std::default_random_engine e(随机种子);
	std::uniform_int_distribution<int32> r(DEF_Min(区间.x, 区间.y), DEF_Max(区间.y, 区间.x));
	return r(e);
}

float32 f_random_F32(int32 随机种子, vec2 区间) {
	std::default_random_engine e(随机种子);
	std::uniform_real_distribution<float32> r(DEF_Min(区间.x, 区间.y), DEF_Max(区间.y, 区间.x));
	float32 v = r(e);
	return v;
}

vec3 f_随机向量(int64 种子, vec2 范围) {
	std::uniform_real_distribution<float32> dis(范围.x, DEF_Max(范围.y, 范围.x));
	std::default_random_engine e(种子);

	return vec3{ dis(e), dis(e), dis(e) };
}

void f_随机向量(std::vector<vec3>& vec, uint64 num, vec2 范围, int32 种子, const vec3& s) {
	std::uniform_real_distribution<float32> dis(范围.x, DEF_Max(范围.y, 范围.x));
	std::default_random_engine e(种子);

	vec.resize(num);
	auto* v = vec.data();

	if (num > 1000) {
		Concurrency::parallel_for<uint32>(0, num, [&](uint32 i) {
			v[i] = vec3{ dis(e), dis(e), dis(e) } *s;
			});
	} else {
		for (uint16 i = 0; i < num; ++i) {
			v[i] = vec3{ dis(e), dis(e), dis(e) } *s;
		}
	}
}

void f_随机向量(std::vector<vec3>& vec, uint64 num, vec2 X, vec2 Y, vec2 Z, int32 种子) {
	std::uniform_real_distribution<float32> dis_x(X.x, X.y);
	std::uniform_real_distribution<float32> dis_y(Y.x, Y.y);
	std::uniform_real_distribution<float32> dis_z(Z.x, Z.y);
	std::default_random_engine e(种子);

	vec.resize(num);
	auto* v = vec.data();

	if (num > 1000) {
#pragma omp parallel for
		for (int64 i = 0; i < num; ++i) {
			v[i] = vec3{ dis_x(e), dis_y(e), dis_z(e) };
		};
	}
	else {
		for (uint64 i = 0; i < num; ++i) {
			v[i] = vec3{ dis_x(e), dis_y(e), dis_z(e) };
		}
	}
}


void f_随机向量(std::vector<vec2>& vec, uint64 num, vec2 范围, int32 种子, const vec2& s) {
	std::uniform_real_distribution<float32> dis(范围.x, DEF_Max(范围.y, 范围.x));
	std::default_random_engine e(种子);

	vec.resize(num);
	auto* v = vec.data();

	if (num > 1000) {
		Concurrency::parallel_for<uint32>(0, num, [&](uint32 i) {
			v[i] = vec2{ dis(e) * s.x, dis(e) * s.y };
			});
	} else {
		for (uint16 i = 0; i < num; ++i) {
			v[i] = vec2{ dis(e) * s.x, dis(e) * s.y };
		}
	}
}

void f_随机向量(std::vector<float32>& vec, uint64 num, vec2 范围, int64 种子) {
	std::uniform_real_distribution<float32> dis(范围.x, DEF_Max(范围.y, 范围.x));
	std::default_random_engine e(种子);

	vec.resize(num);
	auto* v = vec.data();

	if (num > 1000) {
		Concurrency::parallel_for<uint32>(0, num, [&](uint32 i) {
			v[i] = dis(e);
			});
	} else {
		for (uint16 i = 0; i < num; ++i) {
			v[i] = dis(e);
		}
	}
}

vec2 f_随机_向量(float32 最小范围, float32 最大范围, int32 种子) {
	std::uniform_real_distribution<float32> dis(最小范围, 最大范围);
	std::default_random_engine e(种子);

	return vec2{ dis(e), dis(e)};
}


#include <algorithm>
#include <functional>
#include <vector>

void f_random_不重复随机数(int32 最小, int32 最大) {
	

}

vec3 f_random_单位向量() {
	float phi = f_random_getF32() * (3.14159265 * 2.0f);
	float theta = f_random_getF32() * (3.14159265 * 2.0f);

	float cosTheta = cos(theta);
	float sinTheta = sin(theta);

	float cosPhi = cos(phi);
	float sinPhi = sin(phi);

	return {cosTheta * sinPhi, cosPhi, sinTheta * sinPhi};
}

void f_random_向量(S_Vec2Array* vec, vec2 范围, int32 种子, const vec2& s) {
	std::uniform_real_distribution<float32> dis(范围.x, DEF_Max(范围.y, 范围.x));
	std::default_random_engine e(种子);

	for (uint16 i = 0; i < vec->count; ++i) {
		vec->ptr_userData[i] = vec2{ dis(e) * s.x, dis(e) * s.y };
	}

	//if (vec->count > 100000) {
	//	Concurrency::parallel_for<uint32>(0, vec->count, [&](uint32 i) {
	//		vec->ptr_userData[i] = vec2{ dis(e) * s.x, dis(e) * s.y };
	//		});
	//}
	//else {
	//	for (uint16 i = 0; i < vec->count; ++i) {
	//		vec->ptr_userData[i] = vec2{ dis(e) * s.x, dis(e) * s.y };
	//	}
	//}
}
















